﻿#pragma once
#include "zyWindow.h"
#include "../3rdparty/pugixml/pugixml.hpp"

void BlackMoonUI::_计算居中矩形(int imgWidth, int imgHeight, RECT targetRect, RECT& outRect) {
    // 获取目标区域的宽度和高度
    int targetWidth = targetRect.right - targetRect.left;
    int targetHeight = targetRect.bottom - targetRect.top;

    // 计算居中的起始位置
    int startX = (targetWidth - imgWidth) / 2;
    int startY = (targetHeight - imgHeight) / 2;

    // 处理图像尺寸大于目标区域的情况
    if (imgWidth > targetWidth) {
        startX = 0; // 水平方向从 0 开始
        imgWidth = targetWidth; // 裁剪图像宽度
    }
    if (imgHeight > targetHeight) {
        startY = 0; // 垂直方向从 0 开始
        imgHeight = targetHeight; // 裁剪图像高度
    }

    // 设置输出矩形
    outRect.left = targetRect.left + startX;
    outRect.top = targetRect.top + startY;
    outRect.right = outRect.left + imgWidth;
    outRect.bottom = outRect.top + imgHeight;
}
bool BlackMoonUI::OnDrawBack(HWND hwnd, HDC hdc)
{
    RECT rc = { 0 };
    zyObject *pObj = zyEnv::getInstance().getWndObject(hwnd);
    if (pObj->hasPtrData(L"pBackImage") == false && pObj->hasPtrData(L"BackColor") == false)
        return false;
    GetClientRect(hwnd, &rc);
    _画图片(hwnd, hdc, (int)pObj->getPtrData(L"ShowImageType"), rc, (int)pObj->getPtrData(L"pBackImage"), (COLORREF)pObj->getPtrData(L"BackColor"));
    return true;
}
void BlackMoonUI::zyWindow::_画图片_废弃(HWND hwnd, HDC hdc, int type, RECT rc, LONG_PTR pBackImage, int BackColor) {
    // 检查矩形的有效性
    if (rc.right <= rc.left || rc.bottom <= rc.top) {
        return;
    }

    int w = rc.right - rc.left;
    int h = rc.bottom - rc.top;

    BITMAPINFO bi = { 0 };
    bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
    bi.bmiHeader.biWidth = w;
    bi.bmiHeader.biHeight = h;
    bi.bmiHeader.biPlanes = 1;
    bi.bmiHeader.biBitCount = 32;
    bi.bmiHeader.biCompression = BI_RGB;
    BYTE* pBits = nullptr;

    // 使用 RAII 管理 GDI 对象
    struct GDICleanup {
        HDC hdc;
        HBITMAP bitmap;
        GpGraphics* graphics;

        ~GDICleanup() {
            if (graphics) Gdiplus::DllExports::GdipDeleteGraphics(graphics);
            if (bitmap) ::DeleteObject(bitmap);
            if (hdc) ::DeleteDC(hdc);
        }
    } cleanup;

    cleanup.hdc = ::CreateCompatibleDC(hdc);
    if (!cleanup.hdc) return;

    cleanup.bitmap = ::CreateDIBSection(cleanup.hdc, &bi, DIB_RGB_COLORS, (void**)&pBits, NULL, 0);
    if (!cleanup.bitmap) return;

    ::SelectObject(cleanup.hdc, cleanup.bitmap);

    Gdiplus::Status lastResult = DllExports::GdipCreateFromHDC(cleanup.hdc, &cleanup.graphics);
    if (lastResult != Gdiplus::Ok) return;

    if (BackColor == 0)
        BackColor = GetSysColor(COLOR_BTNFACE);

    lastResult = Gdiplus::DllExports::GdipGraphicsClear(cleanup.graphics, zyRGB2ARGB(BackColor, 255));
    if (lastResult != Gdiplus::Ok) return;

    if (pBackImage != 0) {
        Gdiplus::GpImage* image = reinterpret_cast<Gdiplus::GpImage*>(pBackImage);
        switch (type) {
        case 图片显示方式_平铺: 
            lastResult = Gdiplus::DllExports::GdipDrawImage(cleanup.graphics, image, 0, 0);
            if (lastResult != Gdiplus::Ok) return;
            break;
        case 图片显示方式_左上: 
            Gdiplus::DllExports::GdipSetInterpolationMode(cleanup.graphics, InterpolationModeNearestNeighbor);
            Gdiplus::DllExports::GdipSetPixelOffsetMode(cleanup.graphics, PixelOffsetModeHalf);
            lastResult = Gdiplus::DllExports::GdipDrawImageRectI(cleanup.graphics, image, 0, 0, w, h);
            if (lastResult != Gdiplus::Ok) return;
            break;
        case 图片显示方式_缩放: {
            Gdiplus::DllExports::GdipSetSmoothingMode(cleanup.graphics, SmoothingModeHighQuality);
            Gdiplus::DllExports::GdipSetInterpolationMode(cleanup.graphics, InterpolationModeHighQualityBilinear);
            Gdiplus::DllExports::GdipSetPixelOffsetMode(cleanup.graphics, PixelOffsetModeHalf);
            UINT imgWidth;
            UINT imgHeight;
            Gdiplus::DllExports::GdipGetImageWidth(image, &imgWidth);
            Gdiplus::DllExports::GdipGetImageHeight(image, &imgHeight);
            lastResult = Gdiplus::DllExports::GdipDrawImageRectRectI(cleanup.graphics, image, 0, 0, w, h, 0, 0, imgWidth, imgHeight,
                Gdiplus::UnitPixel, NULL, NULL, NULL);
            if (lastResult != Gdiplus::Ok) return;
            break;
        }case 图片显示方式_居中: {
            Gdiplus::DllExports::GdipSetSmoothingMode(cleanup.graphics, SmoothingModeHighQuality);
            Gdiplus::DllExports::GdipSetInterpolationMode(cleanup.graphics, InterpolationModeHighQualityBilinear);
            Gdiplus::DllExports::GdipSetPixelOffsetMode(cleanup.graphics, PixelOffsetModeHalf);
            UINT imgWidth = 0;
            UINT imgHeight = 0;
            Gdiplus::DllExports::GdipGetImageWidth(image, &imgWidth);
            Gdiplus::DllExports::GdipGetImageHeight(image, &imgHeight);
            RECT showRect = { 0 };
            _计算居中矩形(imgWidth, imgHeight, rc, showRect);
            lastResult = Gdiplus::DllExports::GdipDrawImageRectRectI(cleanup.graphics, image, showRect.left, showRect.top,
                showRect.right- showRect.left, showRect.bottom - showRect.top,0,0, imgWidth, imgHeight,
                Gdiplus::UnitPixel, NULL, NULL, NULL);
            if (lastResult != Gdiplus::Ok) return;
            break;
            }
        }
    }

    ::BitBlt(hdc, rc.left, rc.top, w, h, cleanup.hdc, 0, 0, SRCCOPY);
    //if (cleanup.graphics) Gdiplus::DllExports::GdipDeleteGraphics(cleanup.graphics);
    //if (cleanup.bitmap) ::DeleteObject(cleanup.bitmap);
    //if (hdc) ::DeleteDC(hdc);
}
void BlackMoonUI::_画图片(HWND hwnd, HDC hdc, int type, RECT rc, LONG_PTR pBackImage, int BackColor) {
    // 检查矩形的有效性
    if (rc.right <= rc.left || rc.bottom <= rc.top) {
        return;
    }

    int w = rc.right - rc.left;
    int h = rc.bottom - rc.top;

    zyBuffGraphics buff;
    if(!buff.Create(w, h, hdc)) return;

    if (BackColor == 0)
        BackColor = GetSysColor(COLOR_BTNFACE);

    Gdiplus::Graphics* g = buff.GetGraphics();
    Gdiplus::Status lastResult = g->Clear(zyRGB2ARGB(BackColor,255));

    if (pBackImage != 0) {
        Gdiplus::Image* image = reinterpret_cast<Gdiplus::Image*>(pBackImage);
        switch (type) {
        case 图片显示方式_平铺: {
            UINT count = image->GetFrameDimensionsCount();
            std::vector<GUID> dimensionIDs(count);
            image->GetFrameDimensionsList(dimensionIDs.data(), count);
            UINT m_nFrameCount = image->GetFrameCount(&dimensionIDs[0]);
            if (m_nFrameCount < 2) {
                // 不是动画GIF
                Gdiplus::TextureBrush* tbrush = new Gdiplus::TextureBrush(image, Gdiplus::WrapModeTile);
                lastResult = g->FillRectangle(tbrush, 0, 0 ,w ,h);
                delete tbrush;
                if (lastResult != Gdiplus::Ok) return;
            }
            else
            {
                //是gif 手动平铺绘制当前帧
                UINT imgWidth = image->GetWidth();
                UINT imgHeight = image->GetHeight();
                for (int x = 0; x < w; x += imgWidth) {
                    for (int y = 0; y < h; y += imgHeight) {
                        lastResult = g->DrawImage(image, x, y, imgWidth, imgHeight);
                        if (lastResult != Gdiplus::Ok) return;
                    }
                }
            }
            break;
        }  
        case 图片显示方式_左上:
            g->SetInterpolationMode(InterpolationModeNearestNeighbor);
            g->SetPixelOffsetMode(PixelOffsetModeHalf);
            lastResult = g->DrawImage(image, 0, 0, image->GetWidth(), image->GetHeight());
            if (lastResult != Gdiplus::Ok) return;
            break;
        case 图片显示方式_缩放: {
            g->SetSmoothingMode(SmoothingModeHighQuality);
            g->SetInterpolationMode(InterpolationModeHighQualityBilinear);
            g->SetPixelOffsetMode(PixelOffsetModeHalf);
            UINT imgWidth = image->GetWidth();
            UINT imgHeight = image->GetHeight();
            lastResult = g->DrawImage(image, RectF{ 0, 0, (REAL)w, (REAL)h }, 0, 0, (REAL)imgWidth, (REAL)imgHeight, Gdiplus::UnitPixel);
            if (lastResult != Gdiplus::Ok) return;
            break;
        }case 图片显示方式_居中: {
            g->SetSmoothingMode(SmoothingModeHighQuality);
            g->SetInterpolationMode(InterpolationModeHighQualityBilinear);
            g->SetPixelOffsetMode(PixelOffsetModeHalf);
            UINT imgWidth = image->GetWidth();
            UINT imgHeight = image->GetHeight();
            RECT showRect = { 0 };
            _计算居中矩形(imgWidth, imgHeight, rc, showRect);
            lastResult = g->DrawImage(image, RectF{ (REAL)showRect.left, (REAL)showRect.top,
                (REAL)(showRect.right - showRect.left), (REAL)(showRect.bottom - showRect.top) }, 0, 0, (REAL)imgWidth, (REAL)imgHeight, Gdiplus::UnitPixel);
            if (lastResult != Gdiplus::Ok) return;
            break;
        }
        }
    }

    buff.Copy2dc(hdc, rc.left, rc.top, w, h, 0, 0, SRCCOPY);
}
BOOL BlackMoonUI::zyWindow::_CreateWindow(HWND parent,const std::wstring& windowName,
                    POINT pos, POINT size, HMENU hMenu, DWORD style, DWORD exStyle, const std::wstring& className) {
    HWND hWnd = getHwnd();
    if (hWnd)
        return false;
    _SetWindowBorder(getBorder(), style, exStyle);
    //zyEnv::getInstance().dpiConvert(pos);
    //zyEnv::getInstance().dpiConvert(size);
    hWnd = CreateWindowEx(exStyle, className.c_str(), windowName.c_str(), style, pos.x, pos.y,size.x, size.y, parent, hMenu,
                            zyEnv::getInstance().getHandle(),getObject());
    return hWnd != nullptr;
}

BOOL BlackMoonUI::zyWindow::_CreateDialog(HWND parent,const std::wstring& windowName, POINT pos,
                    POINT size, DWORD style, DWORD exStyle, const std::wstring& className) {
    HWND hWnd = getHwnd();
    if (hWnd)
        return false;
    _SetWindowBorder(getBorder(), style, exStyle);
    zyEnv::getInstance().dpiConvert(pos);
    zyEnv::getInstance().dpiConvert(size);
    DLGTEMPLATE lpTemplate = { (DWORD)style,(DWORD)exStyle,0,(short)pos.x,(short)pos.y,(short)size.x,(short)size.y };
    size_t classLen, titleLen;
    classLen = !className.empty() ? (size_t)className.length() * 2 : 2;
    titleLen = !windowName.empty() ? (size_t)windowName.length() * 2 : 2;
    size_t buffLen = sizeof(DLGTEMPLATE) + classLen + titleLen + 6;
    char* m_buff = new char[buffLen];
    memset(m_buff, 0, buffLen);
    *(LPDLGTEMPLATE)m_buff = lpTemplate;
    char* p = m_buff + sizeof(DLGTEMPLATE) + 2;

    if (!className.empty()) {
        memcpy(p, className.c_str(), classLen);
        p += classLen;

        WNDCLASSEX wcex = { 0 };
        wcex.cbSize = sizeof(WNDCLASSEX);
        GetClassInfoEx(zyEnv::getInstance().getHandle(), L"#32770", &wcex);
        wcex.lpszClassName = className.c_str();
        RegisterClassEx(&wcex);
    }
    p += 2;
    if (!windowName.empty()) memcpy(p, windowName.c_str(), titleLen);
    hWnd = CreateDialogIndirectParam(zyEnv::getInstance().getHandle(), (LPCDLGTEMPLATE)m_buff, parent,
                                        (DLGPROC)WinProc_Dialog, (LPARAM)getObject());
    delete[] m_buff;
    return hWnd != nullptr;
}

INT_PTR BlackMoonUI::zyWindow::_LoadDialog(HWND parent,const std::wstring& windowName,POINT pos, POINT size, DWORD style, DWORD exStyle,
                    const std::wstring& className) {
    HWND hWnd = getHwnd();
    if (hWnd)
        return 0;
    _SetWindowBorder(getBorder(), style, exStyle);
    zyEnv::getInstance().dpiConvert(pos);
    zyEnv::getInstance().dpiConvert(size);
    DLGTEMPLATE lpTemplate = { (DWORD)style,(DWORD)exStyle,0,(short)pos.x,(short)pos.y,(short)size.x,(short)size.y };
    size_t classLen, titleLen;
    classLen = !className.empty() ? (size_t)className.length() * 2 : 2;
    titleLen = !windowName.empty() ? (size_t)windowName.length() * 2 : 2;
    size_t buffLen = sizeof(DLGTEMPLATE) + classLen + titleLen + 6;
    char* m_buff = new char[buffLen];
    memset(m_buff, 0, buffLen);
    *(LPDLGTEMPLATE)m_buff = lpTemplate;
    char* p = m_buff + sizeof(DLGTEMPLATE) + 2;

    if (!className.empty()) {
        memcpy(p, className.c_str(), classLen);
        p += classLen;

        WNDCLASSEX wcex = { 0 };
        wcex.cbSize = sizeof(WNDCLASSEX);
        GetClassInfoEx(zyEnv::getInstance().getHandle(), L"#32770", &wcex);
        wcex.lpszClassName = className.c_str();
        RegisterClassEx(&wcex);
    }
    p += 2;
    if (!windowName.empty()) memcpy(p, windowName.c_str(), titleLen);
    INT_PTR ret = DialogBoxIndirectParam(zyEnv::getInstance().getHandle(), (LPCDLGTEMPLATEW)m_buff, parent, (DLGPROC)&zyWindow::WinProc_Dialog, (LPARAM)getObject());
    delete[] m_buff;
    return ret;
}

BOOL BlackMoonUI::zyWindow::_CreateDialogFromRC(HWND parent, const std::wstring& rcName, const std::wstring& className) {
    HWND hWnd = getHwnd();
    if (hWnd)
        return false;
    if (!className.empty()) {
        WNDCLASSEXW wndClass = {sizeof(WNDCLASSEXW)};
        GetClassInfoEx(zyEnv::getInstance().getHandle(), L"32770", &wndClass);
        wndClass.lpszClassName = className.c_str();
        RegisterClassEx(&wndClass);
    }
    hWnd = CreateDialogParam(zyEnv::getInstance().getHandle(), rcName.c_str(), parent, (DLGPROC)WinProc_Dialog, (LPARAM)getObject());
    return hWnd != nullptr;
}

INT_PTR BlackMoonUI::zyWindow::_LoadDialogFromRC(HWND parent, const std::wstring& rcName, const std::wstring& className) {
    HWND hWnd = getHwnd();
    if (hWnd)
        return 0;
    if (!className.empty()) {
        WNDCLASSEXW wndClass = {sizeof(WNDCLASSEXW)};
        GetClassInfoEx(zyEnv::getInstance().getHandle(), L"32770", &wndClass);
        wndClass.lpszClassName = className.c_str();
        RegisterClassEx(&wndClass);
    }
    return DialogBoxParam(zyEnv::getInstance().getHandle(), rcName.c_str(), parent, (DLGPROC)WinProc_ModalDialog, (LPARAM)getObject());
}

BOOL BlackMoonUI::zyWindow::_CreateMDIWindow(HWND parent,const std::wstring& windowName, POINT pos, POINT size, DWORD style, const std::wstring& className) {
    HWND hWnd = getHwnd();
    if (hWnd)
        return false;
    DWORD exStyle = 0;
    _SetWindowBorder(getBorder(), style, exStyle);
    zyEnv::getInstance().dpiConvert(pos);
    zyEnv::getInstance().dpiConvert(size);
    hWnd = CreateMDIWindow(className.c_str(), windowName.c_str(),  style, pos.x, pos.y, size.x, size.y, parent,
                            zyEnv::getInstance().getHandle(),(LPARAM)getObject());
    return hWnd != nullptr;
}

BOOL BlackMoonUI::zyWindow::_BindWindow(HWND hWnd) {
    if (!IsWindow(hWnd))
        return FALSE;
    auto newObject = zyEnv::getInstance().getWndObject(hWnd);
    if (newObject)
        return setObject(newObject);
    if (!m_obj->checkSelf())
        return FALSE;

    HWND seleHwnd = getHwnd();
    if (seleHwnd) {
        size_t count = m_obj->getRefCount();
        switch (count) {
        case 0:
            return FALSE;
        case 1:
            m_obj->callDestroy();
            break;
        default:
            m_obj->release();
        }
    }

    if (GetWindowLongPtr(hWnd, GWLP_WNDPROC) != (LONG_PTR)WinProc_SubClass) {
        auto oldWndProc = (void*)SetWindowLongPtr(hWnd, GWLP_WNDPROC, (LONG_PTR)WinProc_SubClass);
        m_obj->setPtrData(L"oldWndProp", oldWndProc);
        m_obj->setPtrData(L"hWnd", hWnd);
        zyEnv::getInstance().registerWnd(hWnd, m_obj);
        return true;
    }
    return FALSE;
}

void BlackMoonUI::zyWindow::_UnbindWindow() {
    HWND hWnd = getHwnd();
    if (hWnd && IsWindow(hWnd)) {
        auto oldWndProc = (LONG_PTR)m_obj->getPtrData(L"oldWndProp");
        if (oldWndProc) {
            SetWindowLongPtr(hWnd, GWLP_WNDPROC, oldWndProc);
            m_obj->setPtrData(L"oldWndProp", nullptr);
        }
        zyEnv::getInstance().unregisterWnd(hWnd);
        m_obj->setPtrData(L"hWnd", nullptr);
    }
}

void BlackMoonUI::zyWindow::取消绑定() { _UnbindWindow(); }

int BlackMoonUI::zyWindow::addZyStyle(int style) {
    size_t oldStyle = (size_t)m_obj->getPtrData(L"zyStyle");
    size_t newStyle = oldStyle | (size_t)style;
    m_obj->setPtrData(L"zyStyle", (void*)newStyle);
    return (int)oldStyle;
}

int BlackMoonUI::zyWindow::添加ZY窗口风格(int ZY窗口风格) { return addZyStyle(ZY窗口风格); }

int BlackMoonUI::zyWindow::removeZyStyle(int style) {
    size_t oldStyle = (size_t)m_obj->getPtrData(L"zyStyle");
    size_t newStyle = oldStyle & (~(size_t)style);
    m_obj->setPtrData(L"zyStyle", (void*)newStyle);
    return (int)oldStyle;
}

int BlackMoonUI::zyWindow::移除ZY窗口风格(int ZY窗口风格) { return removeZyStyle(ZY窗口风格); }

int BlackMoonUI::zyWindow::getZyStyle() const { return (int)(size_t)(m_obj->getPtrData(L"zyStyle")); }

int BlackMoonUI::zyWindow::取ZY窗口风格() const { return getZyStyle(); }

int BlackMoonUI::zyWindow::setZyStyle(int style) {
    size_t oldStyle = (size_t)m_obj->getPtrData(L"zyStyle");
    m_obj->setPtrData(L"zyStyle", (void*)(size_t)style);
    return (int)oldStyle;
}

int BlackMoonUI::zyWindow::置ZY窗口风格(int ZY窗口风格) { return setZyStyle(ZY窗口风格); }

BOOL BlackMoonUI::zyWindow::show(int cmdShow ) { return ShowWindow(getHwnd(), cmdShow); }

BOOL BlackMoonUI::zyWindow::显示窗口(int 显示命令 ) { return show(显示命令); }

LRESULT BlackMoonUI::zyWindow::sendMsg(UINT uMsg, WPARAM wParam, LPARAM lParam) { return SendMessage(getHwnd(), uMsg, wParam, lParam); }

LRESULT BlackMoonUI::zyWindow::postMsg(UINT uMsg, WPARAM wParam, LPARAM lParam) { return PostMessage(getHwnd(), uMsg, wParam, lParam); }

LRESULT BlackMoonUI::zyWindow::发送消息(UINT 消息, WPARAM wParam, LPARAM lParam) { return sendMsg(消息, wParam, lParam); }

LRESULT BlackMoonUI::zyWindow::投递消息(UINT 消息, WPARAM wParam, LPARAM lParam) { return postMsg(消息, wParam, lParam); }

HWND BlackMoonUI::zyWindow::setCapture() { return SetCapture(getHwnd()); }

BOOL BlackMoonUI::zyWindow::releaseCapture() { return ReleaseCapture(); }

HWND BlackMoonUI::zyWindow::捕获鼠标() { return setCapture(); }

BOOL BlackMoonUI::zyWindow::释放鼠标捕获() { return releaseCapture(); }

std::wstring BlackMoonUI::zyWindow::getClassName() const {
    wchar_t className[MAX_PATH] = {0};
    GetClassNameW(getHwnd(), className, MAX_PATH);
    return className;
}

std::wstring BlackMoonUI::zyWindow::取类名() const { return getClassName(); }

VOID BlackMoonUI::zyWindow::置鼠标指针(zyIcon& 参数_光标) {
    HCURSOR hCursor = (HCURSOR)GetMember(L"hCursor");
    if (hCursor != 0)
        DestroyCursor(hCursor);
    hCursor = CopyIcon((HCURSOR)参数_光标.getIcon());
    SetMember(L"hCursor", (LONG_PTR)hCursor);
    //SetCursor(hCursor);
}
BlackMoonUI::zyIcon BlackMoonUI::zyWindow::取鼠标指针() {
    zyIcon 局部_图标;
    局部_图标.setIcon(CopyIcon((HCURSOR)GetMember(L"hCursor")));
    return 局部_图标;
}

BOOL BlackMoonUI::zyWindow::isWindow() const { return IsWindow(getHwnd()); }

BOOL BlackMoonUI::zyWindow::是否已创建() const { return isWindow(); }

void BlackMoonUI::zyWindow::destroy() { sendMsg(WM_CLOSE, 0, 0); }

void BlackMoonUI::zyWindow::销毁() { destroy(); }

void BlackMoonUI::zyWindow::setFocuse() { SetFocus(getHwnd()); }

void BlackMoonUI::zyWindow::获取焦点() { setFocuse(); }

BOOL BlackMoonUI::zyWindow::isFocuse() const { return GetFocus() == getHwnd(); }

BOOL BlackMoonUI::zyWindow::是否有焦点() const { return isFocuse(); }

BOOL BlackMoonUI::zyWindow::置文本(const std::wstring& bt) {
    BOOL fh = SetWindowText(getHwnd(), bt.c_str());
    重画(true);
    return fh;
}
std::wstring BlackMoonUI::zyWindow::取文本() {
    //这个是用 strting 作为缓冲区的基本知识.. 获取到的要求长度是实际文本长度,要预留+1给 \0,  但是 string size 其实不应该包含尾部的 \0 ,处理后要修复回去
    int cd = GetWindowTextLength(getHwnd())+1;//+1 是为了让他支持作为缓冲区
    std::wstring fh;
    //wchar_t ClassName[256];
    fh.resize(cd );
    GetWindowText(getHwnd(), (LPWSTR)fh.c_str(), cd );
    fh.resize(static_cast<std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t>>::size_type>(cd) - 1);//最后-1 修复回来去掉末尾的\0
    return fh;
}

int BlackMoonUI::zyWindow::信息框(const std::wstring& 参数_提示信息, int 参数_按钮, const std::wstring& 参数_窗口标题)
{
    return MessageBox(getHwnd(), 参数_提示信息.c_str(), 参数_窗口标题.c_str(), 参数_按钮);
}
       
RECT BlackMoonUI::zyWindow::getClientRect() const {
    RECT rc = {0};
    GetClientRect(getHwnd(), &rc);
    return rc;
}

RECT BlackMoonUI::zyWindow::取客户区矩形() const { return getClientRect(); }

int BlackMoonUI::zyWindow::getClientWidth() const {
    RECT rc = {0};
    GetClientRect(getHwnd(), &rc);
    return rc.right - rc.left;
}

int BlackMoonUI::zyWindow::取客户区宽度() const { return getClientWidth(); }

int BlackMoonUI::zyWindow::getClientHeight() const {
    RECT rc = {0};
    GetClientRect(getHwnd(), &rc);
    return rc.bottom - rc.top;
}

int BlackMoonUI::zyWindow::取客户区高度() const { return getClientHeight(); }

RECT BlackMoonUI::zyWindow::getRect() const {
    RECT rc = {0};
    HWND hWnd = getHwnd();
    if (!hWnd) return rc;
    GetWindowRect(hWnd, &rc);
    ScreenToClient(GetParent(hWnd), (LPPOINT)&rc);
    ScreenToClient(GetParent(hWnd), (LPPOINT)&rc.right);
    return rc;
}

RECT BlackMoonUI::zyWindow::取矩形() const { return getRect(); }

void BlackMoonUI::zyWindow::setReDraw(BOOL redraw) { sendMsg(WM_SETREDRAW, redraw ? 1 : 0, 0); }

void BlackMoonUI::zyWindow::禁止重画() { setReDraw(FALSE); }

void BlackMoonUI::zyWindow::允许重画() { setReDraw(TRUE); }

void BlackMoonUI::zyWindow::reDraw(RECT* lpRc , BOOL erase ) {
    auto hWnd = getHwnd();
    if (!hWnd) InvalidateRect(hWnd, lpRc, erase);
}

void BlackMoonUI::zyWindow::重画(BOOL 擦除背景 ) { reDraw(NULL, 擦除背景); }

void BlackMoonUI::zyWindow::部分重画(RECT& 矩型, BOOL 擦除背景 ) { reDraw(&矩型, 擦除背景); }

void BlackMoonUI::zyWindow::validateRect() { ValidateRect(getHwnd(), 0); }

void BlackMoonUI::zyWindow::取消重画() { ValidateRect(getHwnd(), 0); }

void BlackMoonUI::zyWindow::updateWindow() { UpdateWindow(getHwnd()); }

void BlackMoonUI::zyWindow::刷新显示() { updateWindow(); }

BOOL BlackMoonUI::zyWindow::moveWindow(int x, int y, int width, int height, BOOL repaint ) {
    auto hWnd = getHwnd();
    if (!hWnd) return FALSE;

   RECT 局部_rect = {0};
   GetWindowRect(hWnd, &局部_rect);
   POINT 局部_pt = {0};
   局部_pt.x = 局部_rect.left;
   局部_pt.y = 局部_rect.top;;
   ScreenToClient(GetParent(hWnd), &局部_pt);
   if (x == -1)
       x = 局部_pt.x;
   if (y == -1)
       y = 局部_pt.y;
   if (width == -1)
       width = 局部_rect.right - 局部_rect.left;
   if (height == -1)
       height = 局部_rect.bottom - 局部_rect.top;
    return MoveWindow(hWnd, x, y, width, height, repaint);
}

BOOL BlackMoonUI::zyWindow::移动(int 左边, int 顶边, int 宽度, int 高度, BOOL 重绘 ) { return moveWindow(左边, 顶边, 宽度, 高度, 重绘); }

void BlackMoonUI::zyWindow::通知边框改变()
{
    SetWindowPos(取窗口句柄(), 0, 0, 0, 0, 0, SWP_NOZORDER | SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE | SWP_FRAMECHANGED);
    //SetWindowPos(取窗口句柄(), 0, 0, 0, 0, 0, SWP_NOOWNERZORDER | SWP_NOSIZE | SWP_NOMOVE | SWP_FRAMECHANGED);
}

void BlackMoonUI::zyWindow::setPos(int x, int y, BOOL repaint ) {
    auto hWnd = getHwnd();
    if (!hWnd) return;
    RECT rc = getClientRect();
    MoveWindow(hWnd, x, y, rc.right - rc.left, rc.bottom - rc.top, repaint);
}

void BlackMoonUI::zyWindow::setSize(int width, int height, BOOL repaint ) {
    auto hWnd = getHwnd();
    if (!hWnd) return;
    RECT rc = getClientRect();
    MoveWindow(hWnd, rc.left, rc.top, width, height, repaint);
}

void BlackMoonUI::zyWindow::置位置(int 左边, int 顶边, BOOL 重绘 ) { setPos(左边, 顶边, 重绘); }

void BlackMoonUI::zyWindow::置大小(int 宽度, int 高度, BOOL 重绘 ) { setSize(宽度, 高度, 重绘); }

POINT BlackMoonUI::zyWindow::getPos() const {
    POINT pt = {0};
    RECT rc = getRect();
    pt.x = rc.left;
    pt.y = rc.top;
    return pt;
}

POINT BlackMoonUI::zyWindow::取位置() const { return getPos(); }

POINT BlackMoonUI::zyWindow::getSize() const {
    POINT pt = {0};
    RECT rc = getRect();
    pt.x = rc.right - rc.left;
    pt.y = rc.bottom - rc.top;
    return pt;
}

POINT BlackMoonUI::zyWindow::取大小() const { return getSize(); }

BOOL BlackMoonUI::zyWindow::setInsertAfter(int mode ) {
    auto hWnd = getHwnd();
    if (!hWnd) return FALSE;
    HWND hWndInsertAfter;
    switch (mode) {
    case 1:
        hWndInsertAfter = HWND_TOP;
        break;
    case 2:
        hWndInsertAfter = HWND_BOTTOM;
        break;
    case 3:
        hWndInsertAfter = HWND_TOPMOST;
        break;
    case 4:
        hWndInsertAfter = HWND_NOTOPMOST;
        break;
    default:
        hWndInsertAfter = HWND_TOP;
    }
    return SetWindowPos(hWnd, hWndInsertAfter, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
}

// mode: 1:top, 2:bottom, 3:topmost, 4:notopmost, default:top
BOOL BlackMoonUI::zyWindow::调整层次(int 调整模式 ) { return setInsertAfter(调整模式); }

HWND BlackMoonUI::zyWindow::setParent(HWND parent) {
    auto hWnd = getHwnd();
    if (!hWnd) return nullptr;
    return SetParent(hWnd, parent);
}

HWND BlackMoonUI::zyWindow::置父窗口(HWND 父窗口句柄) { return setParent(父窗口句柄); }
HWND BlackMoonUI::zyWindow::取父窗口()
{
    return GetParent(取窗口句柄());
}
int BlackMoonUI::zyWindow::左边(int 参数_左边, BOOL 参数_是否立即重画) {//参数留空则为取，否则为置。
    RECT 局部_rect = { 0 };
    POINT 局部_pt = { 0 };
    HWND hwnd = 取窗口句柄();
    GetWindowRect(hwnd, &局部_rect);
    局部_pt.x = 局部_rect.left;
    局部_pt.y = 局部_rect.top;
    ScreenToClient(GetParent(hwnd), &局部_pt);
    if (参数_左边 == 0)
        return 局部_pt.x;
    else
        return MoveWindow(hwnd, 参数_左边, 局部_pt.y, 局部_rect.right - 局部_rect.left, 局部_rect.bottom - 局部_rect.top, 参数_是否立即重画);
}
int BlackMoonUI::zyWindow::顶边(int 参数_顶边, BOOL 参数_是否立即重画) {//参数留空则为取，否则为置。
    RECT 局部_rect = { 0 };
    POINT 局部_pt = { 0 };
    HWND hwnd = 取窗口句柄();
    GetWindowRect(hwnd, &局部_rect);
    局部_pt.x = 局部_rect.left;
    局部_pt.y = 局部_rect.top;
    ScreenToClient(GetParent(hwnd), &局部_pt);
    if (参数_顶边 == 0)
        return 局部_pt.y;
    else
        return MoveWindow(hwnd, 局部_pt.x, 参数_顶边, 局部_rect.right - 局部_rect.left, 局部_rect.bottom - 局部_rect.top, 参数_是否立即重画);
}
int BlackMoonUI::zyWindow::宽度(int 参数_宽度, BOOL 参数_是否立即重画) {//参数留空则为取，否则为置。
    RECT 局部_rect = { 0 };
    POINT 局部_pt = { 0 };
    HWND hwnd = 取窗口句柄();
    GetWindowRect(hwnd, &局部_rect);
    局部_pt.x = 局部_rect.left;
    局部_pt.y = 局部_rect.top;
    ScreenToClient(GetParent(hwnd), &局部_pt);
    if (参数_宽度 == 0)
        return 局部_rect.right - 局部_rect.left;
    else
        return MoveWindow(hwnd, 局部_pt.x, 局部_pt.y, 参数_宽度, 局部_rect.bottom - 局部_rect.top, 参数_是否立即重画);
}
int BlackMoonUI::zyWindow::高度(int 参数_高度, BOOL 参数_是否立即重画) {//参数留空则为取，否则为置。
    RECT 局部_rect = { 0 };
    POINT 局部_pt = { 0 };
    HWND hwnd = 取窗口句柄();
    GetWindowRect(hwnd, &局部_rect);
    局部_pt.x = 局部_rect.left;
    局部_pt.y = 局部_rect.top;
    ScreenToClient(GetParent(hwnd), &局部_pt);
    if (参数_高度 == 0)
        return 局部_rect.bottom - 局部_rect.top;
    else
        return MoveWindow(hwnd, 局部_pt.x, 局部_pt.y, 局部_rect.right - 局部_rect.left, 参数_高度, 参数_是否立即重画);
}
BOOL BlackMoonUI::zyWindow::可视(BOOL 参数_是否可视) {//ShowWindow，参数留空则为取，否则为置。
     return ShowWindow(取窗口句柄(), 参数_是否可视 ? SW_SHOW : SW_HIDE) != 0;
}
BOOL BlackMoonUI::zyWindow::是否可视()
{
    return (::GetWindowLongPtr(getHwnd(), GWL_STYLE) & WS_VISIBLE) != 0;//IsWindowVisible 这个函数感觉有bug，不能判断窗口是否可见
}
BOOL BlackMoonUI::zyWindow::禁止(BOOL 参数_是否禁止) {//EnableWindow，参数留空则为取，否则为置。
    return EnableWindow(取窗口句柄(), !参数_是否禁止);
}
BOOL BlackMoonUI::zyWindow::是否禁止()
{
    return !IsWindowEnabled(取窗口句柄());
}
int BlackMoonUI::zyWindow::取文本长度()
{
    return GetWindowTextLength(取窗口句柄());
}
void BlackMoonUI::zyWindow::置字体(HFONT 参数_字体) {
    HFONT hFont = (HFONT)GetMember(L"hFont");
    if (hFont != 0)
        DeleteObject(hFont);
    HWND hWnd = 取窗口句柄();
    HDC hdc = GetDC(hWnd);
    //g.创建自DC (hdc)
    //hFont = 参数_字体.取字体句柄 (g);
    SetMember(L"hFont", (LONG_PTR)hFont);
    sendMsg(WM_SETFONT, (WPARAM)hFont, 1);
    ReleaseDC(hWnd, hdc);
}
HFONT BlackMoonUI::zyWindow::取字体() {
    HWND hwnd = 取窗口句柄();
    HFONT hFont = (HFONT)sendMsg(WM_GETFONT, 0, 0);
    HDC hdc = GetDC(hwnd);
    /* 	if(hFont == 0)
            局部_字体.创建自默认字体 (hdc);
        else
            局部_字体.创建自字体句柄 (hdc, hFont); */
    ReleaseDC(hwnd, hdc);
    return hFont;
}
void BlackMoonUI::zyWindow::允许文件拖放(BOOL 参数_是否允许拖放)
{
    DragAcceptFiles(取窗口句柄(), 参数_是否允许拖放);
}
BOOL BlackMoonUI::zyWindow::开始时钟(int 参数_时钟周期, int 参数_时钟ID) {
    return SetTimer(取窗口句柄(), 参数_时钟ID, 参数_时钟周期, 0) != 0;
}
BOOL BlackMoonUI::zyWindow::停止时钟(int 参数_时钟ID) {
    return KillTimer(取窗口句柄(), 参数_时钟ID) != 0;
}
BOOL  BlackMoonUI::zyWindow::置布局(zyLayout& 参数_布局) {
    zyObject* pLayout = 参数_布局.getObject();
    if (pLayout == 0) {
        return 0;
    }
    //IUnknown_AddRef(pLayout);
    pLayout->addRef();
    SetMember(L"zyLayout", (LONG_PTR)pLayout);
    RECT rc = 取客户区矩形();
    RECT* pRect = (RECT*)pLayout->getPtrData(L"pRect");
    if(pRect == nullptr)
        return false;
    RtlMoveMemory(pRect, &rc, sizeof(RECT));
    参数_布局.布局();
    return true;
}
LRESULT BlackMoonUI::zyWindow::调用默认窗口过程(UINT 参数_msg, WPARAM 参数_wParam, LPARAM 参数_lParam)
{
    LONG_PTR oldProc = GetMember(L"oldWndProp");
    if (oldProc == 0)
        return DefWindowProc(取窗口句柄(), 参数_msg, 参数_wParam, 参数_lParam);
    else
        return CallWindowProc((WNDPROC)oldProc, 取窗口句柄(), 参数_msg, 参数_wParam, 参数_lParam);
}
DWORD BlackMoonUI::zyWindow::GetStyle() { return (DWORD)GetWindowLongPtr(getHwnd(), GWL_STYLE); }
DWORD BlackMoonUI::zyWindow::SetStyle(DWORD Style) {
    HWND hWnd=取窗口句柄();
    DWORD style = (DWORD)SetWindowLongPtr(hWnd, GWL_STYLE, Style);
    SetWindowPos(hWnd, 0, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED);
    return style;
}
DWORD BlackMoonUI::zyWindow::RemoveStyle(DWORD Style) {
    HWND hWnd = 取窗口句柄();
    DWORD nStyle = (DWORD)GetWindowLongPtr(hWnd, GWL_STYLE);
    nStyle = (DWORD)SetWindowLongPtr(hWnd, GWL_STYLE, nStyle & (~Style));
    SetWindowPos(hWnd, 0, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED);
    return nStyle;
}
DWORD BlackMoonUI::zyWindow::AddStyle(DWORD Style) {
    HWND hWnd = 取窗口句柄();
    DWORD nStyle = (DWORD)GetWindowLongPtr(hWnd, GWL_STYLE);
    nStyle = (DWORD)SetWindowLongPtr(hWnd, GWL_STYLE, nStyle | Style);
    SetWindowPos(hWnd, 0, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED);
    return nStyle;
}
DWORD BlackMoonUI::zyWindow::AddExStyle(DWORD ExStyle) {
    HWND hWnd = 取窗口句柄();
    DWORD nStyle = (DWORD)GetWindowLongPtr(hWnd, GWL_EXSTYLE);
    nStyle = (DWORD)SetWindowLongPtr(hWnd, GWL_EXSTYLE, ExStyle | nStyle);
    SetWindowPos(hWnd, 0, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED);
    return nStyle;
}
DWORD BlackMoonUI::zyWindow::RemoveExStyle(DWORD ExStyle) {
    HWND hWnd = 取窗口句柄();
    DWORD nStyle = (DWORD)GetWindowLongPtr(hWnd, GWL_EXSTYLE);
    nStyle = (DWORD)SetWindowLongPtr(hWnd, GWL_EXSTYLE, nStyle | (~ExStyle));
    SetWindowPos(hWnd, 0, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED);
    return nStyle;
}
DWORD BlackMoonUI::zyWindow::SetExStyle(DWORD ExStyle) {
    HWND hWnd = 取窗口句柄();
    DWORD style = (DWORD)SetWindowLongPtr(hWnd, GWL_EXSTYLE, ExStyle);
    SetWindowPos(hWnd, 0, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED);
    return style;
}
DWORD BlackMoonUI::zyWindow::GetExStyle() {
    return (DWORD)GetWindowLongPtr(取窗口句柄(), GWL_EXSTYLE);
}
int BlackMoonUI::zyWindow::取属性名列表(std::vector<std::wstring> 参数_属性名数组)
{
    if (EnumPropsEx(取窗口句柄(), &EnumPropCallback_Name, (ULONG_PTR)参数_属性名数组.data()) ==-1)
        return 0;
    
    return (int)参数_属性名数组.size();
}
BOOL CALLBACK BlackMoonUI::zyWindow::EnumPropCallback_Name(HWND hwnd,LPWSTR lpszString,HANDLE hData,ULONG_PTR lParam) {
    if (hData == nullptr)
        return FALSE;
    std::vector<std::wstring>* dwData = reinterpret_cast<std::vector<std::wstring>*>(lParam);
    
    if (lpszString) {
        if (HIWORD(lpszString)==0) {
            wchar_t buffer[256]; // 增加缓冲区大小以避免溢出
            GetAtomName((ATOM)(LONG_PTR)(lpszString), buffer, _countof(buffer));
            dwData->push_back(buffer);
        }
        else{
            dwData->push_back(lpszString);
        }
    }
    return TRUE; // 继续遍历下一个窗口
}
BOOL BlackMoonUI::zyWindow::EnumPropCallback_Value(HWND hwnd, LPWSTR lpszString, HANDLE hData, ULONG_PTR lParam){
    // 检查传入的指针是否有效
    if (hData == nullptr)
        return FALSE; 
    // 获取传递的 vector<int> 指针
    std::vector<int>* dwData = reinterpret_cast<std::vector<int>*>(lParam);
    // 将 HANDLE 转换为 int 并插入到 vector 中
    // 假设 HANDLE 可以安全地转换为 int
    // 如果 HANDLE 的值超出了 int 的范围，需要考虑其他方式处理
    int dataValue = static_cast<int>(reinterpret_cast<INT_PTR>(hData));
    dwData->push_back(dataValue);
    return TRUE;
}
int BlackMoonUI::zyWindow::取属性值列表(std::vector<int> 参数_属性值数组)
{
    if (EnumPropsEx(取窗口句柄(), &EnumPropCallback_Value, (ULONG_PTR)参数_属性值数组.data()) == -1)
        return 0;

    return (int)参数_属性值数组.size();
}
void BlackMoonUI::zyWindow::通用事件_鼠标位置被移动(TRegEvent* 参数_事件指针) {
    SetRegEvent(L"OnMouseMove", 参数_事件指针);
}
void BlackMoonUI::zyWindow::通用事件_重画(TRegEvent* 参数_事件指针) {
    SetRegEvent(L"OnPaint", 参数_事件指针);
}
void BlackMoonUI::zyWindow::通用事件_鼠标左键被按下(TRegEvent* 参数_事件指针) {
    SetRegEvent(L"OnLButtonDown", 参数_事件指针);
}
void BlackMoonUI::zyWindow::通用事件_鼠标左键被放开(TRegEvent* 参数_事件指针) {
    SetRegEvent(L"OnLButtonUp", 参数_事件指针);
}
void BlackMoonUI::zyWindow::通用事件_被双击(TRegEvent* 参数_事件指针) {
    SetRegEvent(L"OnLButtonDblClk", 参数_事件指针);
}
void BlackMoonUI::zyWindow::通用事件_鼠标右键被按下(TRegEvent* 参数_事件指针) {
    SetRegEvent(L"OnRButtonDown", 参数_事件指针);
}
void BlackMoonUI::zyWindow::通用事件_鼠标右键被放开(TRegEvent* 参数_事件指针) {
    SetRegEvent(L"OnRButtonUp", 参数_事件指针);
}
void BlackMoonUI::zyWindow::通用事件_鼠标移入(TRegEvent* 参数_事件指针) {
    SetMember(L"EnlableHover", 1);
    SetRegEvent(L"OnMouseIn", 参数_事件指针);
}
void BlackMoonUI::zyWindow::通用事件_鼠标悬停(TRegEvent* 参数_事件指针) {
    SetMember(L"EnlableHover", 1);
    SetRegEvent(L"OnMouseHover", 参数_事件指针);
}
void BlackMoonUI::zyWindow::通用事件_鼠标离开(TRegEvent* 参数_事件指针) {
    SetMember(L"EnlableHover", 0);
    SetRegEvent(L"OnMouseLeave", 参数_事件指针);
}
void BlackMoonUI::zyWindow::通用事件_获取焦点(TRegEvent* 参数_事件指针) {
    SetRegEvent(L"OnSetFocus", 参数_事件指针);
}
void BlackMoonUI::zyWindow::通用事件_失去焦点(TRegEvent* 参数_事件指针) {
    SetRegEvent(L"OnKillFocus", 参数_事件指针);
}
void BlackMoonUI::zyWindow::通用事件_按下某键(TRegEvent* 参数_事件指针) {
    SetRegEvent(L"OnKeyDown", 参数_事件指针);
}
void BlackMoonUI::zyWindow::通用事件_放开某键(TRegEvent* 参数_事件指针) {
    SetRegEvent(L"OnKeyUp", 参数_事件指针);
}
void  BlackMoonUI::zyWindow::通用事件_滚轮被滚动(TRegEvent* 参数_事件指针) {
    SetRegEvent(L"OnMouseWheel", 参数_事件指针);
}
void  BlackMoonUI::zyWindow::通用事件_字符输入(TRegEvent* 参数_事件指针) {
    SetRegEvent(L"OnChar", 参数_事件指针);
}
void  BlackMoonUI::zyWindow::通用事件_文件拖放(TRegEvent* 参数_事件指针) {
    SetRegEvent(L"OnDropFiles", 参数_事件指针);
}
void  BlackMoonUI::zyWindow::通用事件_时钟(TRegEvent* 参数_事件指针) {
    SetRegEvent(L"OnTimer", 参数_事件指针);
}
void  BlackMoonUI::zyWindow::通用事件_窗口消息(TRegEvent* 参数_事件指针){
    SetRegEvent(L"OnWndMsg", 参数_事件指针);
}
int BlackMoonUI::zyWindow::边框(int Border) {
    int nBorder = getBorder();
    if (Border != -1) {
        setBorder(Border);
        if (是否已创建()) {
            HWND hWnd = getHwnd();
            DWORD style = (DWORD)GetWindowLongPtr(hWnd, GWL_STYLE);
            DWORD exStyle = (DWORD)GetWindowLongPtr(hWnd, GWL_EXSTYLE);
            _设置控件边框(Border, style, exStyle);
            SetWindowLongPtr(hWnd, GWL_STYLE, style);
            SetWindowLongPtr(hWnd, GWL_EXSTYLE, exStyle);
            SetWindowPos(hWnd, 0, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED);
        }
    }
    return nBorder;
}
void BlackMoonUI::zyWindow::_SetWindowBorder(int mode, DWORD& style, DWORD& exStyle) {
    if (hasBorder()) {
        style &= ~(WS_POPUP | WS_SYSMENU | WS_CAPTION | WS_BORDER | WS_DLGFRAME | WS_SIZEBOX);
        exStyle &= ~(WS_EX_OVERLAPPEDWINDOW | WS_EX_TOOLWINDOW);
        switch (mode) {
        case 窗口边框_无边框:
            style |= WS_POPUP;
            break;
        case 窗口边框_普通可调边框 :
            style |= WS_SYSMENU | WS_CAPTION | WS_BORDER | WS_DLGFRAME | WS_SIZEBOX;
            exStyle |= WS_EX_WINDOWEDGE;
            break;
        case 窗口边框_普通固定边框:
            style |= WS_SYSMENU | WS_CAPTION | WS_BORDER | WS_DLGFRAME;
            exStyle |= WS_EX_WINDOWEDGE;
            break;
        case 窗口边框_窄标题可调边框:
            style |= WS_SYSMENU | WS_CAPTION | WS_BORDER | WS_DLGFRAME | WS_SIZEBOX;
            exStyle |= WS_EX_WINDOWEDGE | WS_EX_TOOLWINDOW;
            break;
        case 窗口边框_窄标题固定边框:
            style |= WS_SYSMENU | WS_CAPTION | WS_BORDER | WS_DLGFRAME;
            exStyle |= WS_EX_WINDOWEDGE | WS_EX_TOOLWINDOW;
            break;
        case 窗口边框_镜框式可调边框:
            style |= WS_SYSMENU | WS_CAPTION | WS_BORDER | WS_DLGFRAME | WS_SIZEBOX;
            exStyle |= WS_EX_OVERLAPPEDWINDOW;
            break;
        case 窗口边框_镜框式固定边框:
            style |= WS_SYSMENU | WS_CAPTION | WS_BORDER | WS_DLGFRAME;
            exStyle |= WS_EX_OVERLAPPEDWINDOW;
            break;
        default:
            style |= WS_SYSMENU | WS_CAPTION | WS_BORDER | WS_DLGFRAME;
            exStyle |= WS_EX_WINDOWEDGE;
            break;
        }
    }
}

void BlackMoonUI::zyWindow::设置窗口边框(int mode, DWORD& style, DWORD& exStyle) { return _SetWindowBorder(mode, style, exStyle); }

void BlackMoonUI::zyWindow::_设置控件边框(int 参数_边框, DWORD& 参数_风格, DWORD& 参数_扩展风格)
{
    if (HasMember(L"Border") == false)
        return;
    参数_风格 &= ~WS_BORDER;
    参数_扩展风格 &= ~(WS_EX_OVERLAPPEDWINDOW | WS_EX_STATICEDGE);
    if (参数_边框 == 控件边框_无边框)
        参数_扩展风格 = NULL;
    if (参数_边框 == 控件边框_凹入式)
        参数_扩展风格 |= WS_EX_CLIENTEDGE;
    else if (参数_边框 == 控件边框_突出式)
        参数_扩展风格 |= WS_EX_WINDOWEDGE;
    else if (参数_边框 == 控件边框_浅凹入式)
        参数_扩展风格 |= WS_EX_STATICEDGE;
    else if (参数_边框 == 控件边框_镜框式)
        参数_扩展风格 |= WS_EX_OVERLAPPEDWINDOW;
    else if (参数_边框 == 控件边框_单线边框式)
        参数_风格 |= WS_BORDER;
}
//超类化
BOOL BlackMoonUI::zyWindow::zyWindow_SuperClass(const std::wstring& className, const std::wstring& newClassName)
{
    WNDCLASSEX wcex = { 0 };
    wcex.cbSize = sizeof(wcex);
    if (!GetClassInfoEx(0, className.c_str(), &wcex))
        return FALSE;

    // 保存原始窗口过程
    WNDPROC oldWndProc = wcex.lpfnWndProc;
    wcex.lpfnWndProc = &WinProc_SuperClass;
    //wcex.hInstance = zyEnv::getInstance().getHandle();
    wcex.lpszClassName = newClassName.c_str();
    SetMember(L"oldWndProc", (LONG_PTR)oldWndProc);
    // 注册新的窗口类
    RegisterClassEx(&wcex);

    return TRUE;
}
void BlackMoonUI::zyWindow::zyWindow_Destroy(zyObject* obj) {
    zyWindow_OnNCDestroy(obj);
    zyBase_Destroy(obj);
}
LRESULT CALLBACK BlackMoonUI::zyWindow::zyWindow_WndProc(zyObject* obj, HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL* bHandled) {
    switch (uMsg) {
    case WM_NCDESTROY:
        zyWindow_OnNCDestroy(obj);
        break;
    case WM_SETCURSOR: {
        auto ret = zyWindow_OnSetCursor(obj, hWnd, uMsg, wParam, lParam);
        if (ret) {
            *bHandled = TRUE;
            return ret;
        }
        break;
    }
    }
    return zyBase_WndProc(obj, hWnd, uMsg, wParam, lParam, bHandled);
}
    
void BlackMoonUI::zyWindow::zyWindow_OnNCDestroy(zyObject* obj) {
    auto hCursor = (HCURSOR)obj->getPtrData(L"hCursor");
    if (hCursor) {
        DestroyCursor(hCursor);
        obj->setPtrData(L"hCursor", nullptr);
    }
    auto hFont = (HFONT)obj->getPtrData(L"hFont");
    if (hFont) {
        DeleteObject(hFont);
        obj->setPtrData(L"hFont", nullptr);
    }

    //auto* Controls = static_cast<std::unordered_map<std::wstring, LPVOID>*>(obj->getPtrData(L"Controls"));
    //if (Controls) {
    //    for (const auto& pair : *Controls) {
    //        zyObject* pControl = (zyObject*)pair.second;
    //        if (pControl)
    //            pControl->release();
    //        //std::wcout << pair.second << std::endl;
    //    }
    //    // todo Controls handle release
    //    Controls->clear();
    //    delete Controls;
    //    obj->setPtrData(L"Controls", nullptr);
    //}
    obj->removePtrData(L"Border");
    //会崩溃
    /*pugi::xml_node* XmlNode = (pugi::xml_node*)obj->getPtrData(L"XmlNode");
    if (XmlNode)
        delete XmlNode;*/
}

        
LRESULT CALLBACK BlackMoonUI::zyWindow::zyWindow_OnSetCursor(zyObject* obj, HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
    auto hCursor = (HCURSOR)obj->getPtrData(L"hCursor");
    auto objHwnd = (HWND)obj->getPtrData(L"hWnd");
    if (hCursor && LOWORD(lParam) == HTCLIENT && (HWND)wParam == objHwnd)
        return SetCursor(hCursor) ? TRUE : FALSE;
    return 0;
}

LRESULT CALLBACK BlackMoonUI::zyWindow::WinProc_SubClass(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
    auto obj = zyEnv::getInstance().getWndObject(hWnd);
    if (obj) {
        BOOL bHand = FALSE;
        auto ret = obj->callWndProc(hWnd, uMsg, wParam, lParam, &bHand);
        if (bHand)
            return ret;
        auto oldWndProc = (WNDPROC)obj->getPtrData(L"oldWndProp");
        if (oldWndProc) {
            return CallWindowProc(oldWndProc, hWnd, uMsg, wParam, lParam);
        }
    }
    return DefSubclassProc(hWnd, uMsg, wParam, lParam);
}

LRESULT CALLBACK BlackMoonUI::zyWindow::WinProc_SuperClass(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
    if (uMsg == WM_NCCREATE) {
        CREATESTRUCT* pcs = reinterpret_cast<CREATESTRUCT*>(lParam);
        zyObject* obj = *(reinterpret_cast<zyObject**>(pcs->lpCreateParams));
        if (obj != nullptr) {
            obj->setPtrData(L"hWnd", hWnd);
            zyEnv::getInstance().registerWnd(hWnd, obj);
        }
    }
    zyObject* Ptr = zyEnv::getInstance().getWndObject(hWnd);
    if (Ptr) {
        BOOL bHand = FALSE;
        auto ret = Ptr->callWndProc(hWnd, uMsg, wParam, lParam, &bHand);
        if (bHand)
            return ret;
        auto oldWndProc = (WNDPROC)Ptr->getPtrData(L"oldWndProc");
        if (oldWndProc) {
            return CallWindowProc(oldWndProc, hWnd, uMsg, wParam, lParam);
        }
    }
    return DefWindowProc(hWnd, uMsg, wParam, lParam);
}

LRESULT CALLBACK BlackMoonUI::zyWindow::WinProc_Dialog(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
    if (uMsg == WM_INITDIALOG) {
        if (lParam) {
            auto oldStyle = GetClassLongPtr(hWnd, GCL_STYLE);
            SetClassLongPtr(hWnd, GCL_STYLE, oldStyle | CS_HREDRAW | CS_VREDRAW);
            ((zyObject*)lParam)->setPtrData(L"hWnd", hWnd);
            zyEnv::getInstance().registerWnd(hWnd, (zyObject*)lParam);
        }
    }
    auto obj = zyEnv::getInstance().getWndObject(hWnd);
    if (obj) {
        BOOL bHand = FALSE;
        auto ret = obj->callWndProc(hWnd, uMsg, wParam, lParam, &bHand);
        if (bHand)
            return ret;
    }
    if (uMsg == WM_CLOSE) {
        if (obj) {
            INT_PTR DialogResult = (INT_PTR)obj->getPtrData(L"DialogResult");
            EndDialog(hWnd, DialogResult);
        }
    }
    return 0;
}

LRESULT CALLBACK BlackMoonUI::zyWindow::WinProc_ModalDialog(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
    if (uMsg == WM_INITDIALOG) {
        if (lParam) {
            auto oldStyle = GetClassLongPtr(hWnd, GCL_STYLE);
            SetClassLongPtr(hWnd, GCL_STYLE, oldStyle | CS_HREDRAW | CS_VREDRAW);
            ((zyObject*)lParam)->setPtrData(L"hWnd", hWnd);
            zyEnv::getInstance().registerWnd(hWnd, (zyObject*)lParam);
        }
    }

    auto obj = zyEnv::getInstance().getWndObject(hWnd);
    if (obj) {
        BOOL bHand = FALSE;
        auto ret = obj->callWndProc(hWnd, uMsg, wParam, lParam, &bHand);
        if (bHand)
            return ret;
    }

    if (uMsg == WM_CLOSE) {
        if (obj) {
            INT_PTR iDialogResult = (INT_PTR)obj->getPtrData(L"DialogResult");
            EndDialog(hWnd, iDialogResult);
        }
    }
    return 0;
}

